package com.tianji.aigc.service.impl;

import com.alibaba.cloud.ai.dashscope.api.DashScopeAudioTranscriptionApi;
import com.alibaba.cloud.ai.dashscope.audio.DashScopeAudioSpeechOptions;
import com.alibaba.cloud.ai.dashscope.audio.DashScopeAudioTranscriptionOptions;
import com.alibaba.cloud.ai.dashscope.audio.synthesis.SpeechSynthesisModel;
import com.alibaba.cloud.ai.dashscope.audio.synthesis.SpeechSynthesisPrompt;
import com.alibaba.cloud.ai.dashscope.audio.synthesis.SpeechSynthesisResponse;
import com.alibaba.cloud.ai.dashscope.audio.transcription.AudioTranscriptionModel;
import com.tianji.aigc.service.AudioService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.audio.transcription.AudioTranscriptionPrompt;
import org.springframework.ai.audio.transcription.AudioTranscriptionResponse;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
import reactor.core.publisher.Flux;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
import java.nio.file.Files;
import com.alibaba.cloud.ai.dashscope.api.DashScopeAudioSpeechApi;
@Slf4j
@Service
@ConditionalOnProperty(prefix = "tj.ai", name = "audio-type", havingValue = "ALIYUN")
@RequiredArgsConstructor
public class AliYunAudioServiceImpl implements AudioService {
    private final SpeechSynthesisModel speechSynthesisModel;
    private final AudioTranscriptionModel transcriptionModel;

    @Override
    public ResponseBodyEmitter ttsStream(String text) {
        var emitter = new ResponseBodyEmitter();
        Flux<SpeechSynthesisResponse> response = speechSynthesisModel.stream(
                new SpeechSynthesisPrompt(
                        text,
                        DashScopeAudioSpeechOptions.builder()
                                .model(DashScopeAudioSpeechApi.AudioSpeechModel.SAM_BERT_ZHITING_V1.getValue())
                                .build()
                )
        );

        response.subscribe(synthesisResponse -> {
                    // 获取响应输出的数据，并发送到响应体中
            ByteBuffer byteBuffer = synthesisResponse.getResult().getOutput().getAudio();
                    byte[] bytes = new byte[byteBuffer.remaining()];
                    byteBuffer.get(bytes); // 将ByteBuffer内容读取到bytes数组
                    try {
                        emitter.send(bytes);
                    } catch (IOException e) {
                        log.error("发送音频数据失败", e);
                        emitter.completeWithError(e);
                    }
                },
                emitter::completeWithError,
                emitter::complete
        );

        // 返回emitter
        return emitter;
    }
    private static final String DEFAULT_MODEL = DashScopeAudioTranscriptionApi.AudioTranscriptionModel.PARAFORMER_REALTIME_V2.getValue();
    @Override
    public String stt(MultipartFile multipartFile) {
        String currentDir = "X:\\file\\gb168";
        String name = UUID.randomUUID().toString() + ".wav";
        // 创建临时MP3文件路径
        Path tempMp3Path = Paths.get(currentDir, name);

        try {
            // 将MultipartFile转换为MP3并保存到临时文件
            convertToMp3(multipartFile, tempMp3Path);
            String url = "https://bz.spc.org.cn/bw/file/gb168/" + name;
            // 使用临时MP3文件进行语音识别
            AudioTranscriptionResponse response = transcriptionModel.call(
                    new AudioTranscriptionPrompt(
                            new UrlResource(url),
                            DashScopeAudioTranscriptionOptions.builder()
                                    .withModel(DEFAULT_MODEL)
                                    .build()
                    )
            );

            return response.getResult().getOutput();
        } catch (Exception e) {
            log.error("语音识别处理失败", e);
            throw new RuntimeException("语音识别处理失败", e);
        } finally {
            // 删除临时MP3文件
            try {
                Files.deleteIfExists(tempMp3Path);
                log.info("临时MP3文件已删除: {}", tempMp3Path);
            } catch (IOException e) {
                log.error("删除临时MP3文件失败", e);
            }
        }
    }

    /**
     * 直接保存MultipartFile为MP3文件
     */
    private void convertToMp3(MultipartFile sourceFile, Path targetPath) throws IOException {
        // 直接将MultipartFile内容保存到目标MP3文件
        sourceFile.transferTo(targetPath);
    }


}